/**
 * @file ringArray.c
 * @author xzq@domain.com
 * @brief
 * @version 0.1
 * @date 2024-10-26
 *
 * @copyright Copyright (c) 2024
 *
 */
#include "string.h"
#include "stdlib.h"
#include "stdio.h"
#include "ringArray.h"

#define TAG "RINGARRAY"
#define LOG_MESSAGE_DEBUG(TAG, ...)

/**
 * @brief xRingArray Memery Malloc
 *
 * @param size Malloc Size
 * @return void*
 */
static void *xRingArrayMalloc(size_t size)
{
	return malloc(size);
}

/**
 * @brief xRingArray Free Memery
 *
 * @param memery Malloc Memery Address
 */
static void xRingArrayFree(void *memery)
{
	free(memery);
}

/**
 * @brief xRingArray Create
 *
 * @param rb xRingArray_t *rb
 * @param size xRingArray Buffer Size
 * @return raStatus_t
 */
raStatus_t xRingArrayCreate(xRingArray_t *rb, uint32_t size)
{
	if ((NULL == rb) || (size <= 0))
	{
		return raFalse;
	}
	rb->date = (int8_t *)xRingArrayMalloc(size);
	if (NULL == rb->date)
	{
		return raFalse;
	}
	rb->head = 0;
	rb->tail = 0;
	rb->date_max = size;
	return raTrue;
}

/**
 * @brief xRingArray Destory
 *
 * @param rb xRingArray_t *rb
 * @return raStatus_t
 */
raStatus_t xRingArrayDestory(xRingArray_t *rb)
{
	if (NULL == rb)
	{
		return raFalse;
	}
	rb->date_max = 0;
	rb->head = 0;
	rb->tail = 0;
	xRingArrayFree(rb->date);
	rb->date = NULL;
	return raTrue;
}

/**
 * @brief xRingArray Can Read Avaliable
 *
 * @param rb xRingArray_t *rb
 * @return uint32_t
 */
uint32_t xRingArrayAvailable(xRingArray_t *rb)
{
	if (NULL == rb)
	{
		return 0;
	}
	return (rb->date_max + rb->head - rb->tail) % rb->date_max;
}

/**
 * @brief xRingArray Write One Byte
 *
 * @param rb xRingArray_t *rb
 * @param c write Charactor
 * @return raStatus_t
 */
raStatus_t xRingArrayWrite(xRingArray_t *rb, uint8_t c)
{
	if (NULL == rb)
	{
		return raFalse;
	}
	uint32_t i = (rb->head + 1) % rb->date_max;
	if (i == rb->tail)
	{
		return raFalse;
	}
	rb->date[rb->head] = (int8_t)c;
	rb->head = i;
	return raTrue;
}
/**
 * @brief xRingArray Read One Byte
 *
 * @param rb xRingArray_t *rb
 * @param c read Buffer
 * @return raStatus_t
 */
raStatus_t xRingArrayRead(xRingArray_t *rb, void *c)
{
	if ((NULL == rb) || (NULL == c))
	{
		return raFalse;
	}
	int8_t *rc = (int8_t *)c;
	*rc = 0;
	if (rb->head == rb->tail)
	{
		return raFalse;
	}
	*rc = rb->date[rb->tail];
	rb->tail = (rb->tail + 1) % rb->date_max;
	return raTrue;
}

/**
 * @brief xRingArray Buffer Flush
 *
 * @param rb xRingArray_t *rb)
 * @return raStatus_t
 */
raStatus_t xRingArrayFlush(xRingArray_t *rb)
{
	if (NULL == rb)
	{
		return raFalse;
	}
	memset(rb->date, 0, rb->date_max);
	rb->head = 0;
	rb->tail = 0;
	return raTrue;
}